package org.pblue.tumblarity.controller;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.pblue.appengine.AppengineDataException;
import org.pblue.tumblarity.data.bean.Event;
import org.pblue.tumblarity.data.bean.Tumblelog;
import org.pblue.tumblarity.task.Compare;
import org.pblue.tumblarity.tools.EventComparator;

/**
 * This is a controller for ajax calls from track.jsp, mapped to /controller/listevents.
 * 
 * @author mikolaj
 *
 */
public class ListEvents extends HttpServlet {

  private static final long serialVersionUID = 1L;
  
  public static final String REDIRECT_MESSAGE = "REDIRECT";
  public static final String NONE_MESSAGE = "NONE";
  public static final String REQUEST_PARAM_TUMBLELOG_ID = "tumblelogId";
  
  private static final Logger log = Logger.getLogger(ListEvents.class.getName());

  @Override
  protected void service(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException {
    // get the tumblelog id, and retrieve that tumblelog
    // from the datastore
    String tumblelogId = (String) pRequest.getParameter(REQUEST_PARAM_TUMBLELOG_ID);
    
    Tumblelog tumblelog = null;
    try {
      tumblelog = Tumblelog.get(tumblelogId);
    } catch (AppengineDataException e) {
      log.warning("Couldn't retrieve " + tumblelogId);
    }
    
    // send a message to redirect, if the tumblelog hasn't been found in
    // the datastore
    if (tumblelog == null) {
      pResponse.getWriter().write(REDIRECT_MESSAGE);
      return;
    }
    
    // send a message to redirect, if the tumblelog doesn't authenticate
    if (!tumblelog.authenticateRequest(pRequest)) {
      pResponse.getWriter().write(REDIRECT_MESSAGE);
      return;
    }
    
    // send a message to redirect, if the tumblelog's state is ERROR
    if (tumblelog.getFetchState() == Tumblelog.FETCH_STATE_ERROR) {
      pResponse.getWriter().write(REDIRECT_MESSAGE);
      return;
    }
    
    String response = "";
    
    try {
      // get the list of events of the tumblelog and sort them by descending
      // order of date
      List<Event> events = tumblelog.getEvents();
      
      // check if there are any messages for this tumblelog, and build a
      // json array of these, if so
      if (events != null && tumblelog.getLastFetched() != null) {
        Collections.sort(events, new EventComparator());
        
        JSONArray array = new JSONArray();
        for (Event event : events) {
          JSONObject json = new JSONObject(event.getMessage());
          json.append(Compare.JSON_KEY_ID, event.getId());
          array.put(json);
        }
        response = array.toString();
        
      // send an empty message, if no events were found
      } else {
        response = NONE_MESSAGE;
      }
      
    } catch (JSONException e) {
      response = NONE_MESSAGE;
      log.log(Level.SEVERE, "Couldn't retrieve list of events of tumblelog " + tumblelogId, e);
    } catch (AppengineDataException e) {
      response = NONE_MESSAGE;
      log.log(Level.SEVERE, "Couldn't retrieve list of events of tumblelog " + tumblelogId, e);
    }
    
    pResponse.getWriter().write(response);
  }

}
